home *** CD-ROM | disk | FTP | other *** search
/ Monster Media 1994 #2 / Monster Media No. 2 (Monster Media)(1994).ISO / prog_pas / sk210f.zip / TESTFIN.PAS < prev    next >
Pascal/Delphi Source File  |  1994-05-15  |  16KB  |  439 lines

  1. {$I SHDEFINE.INC}
  2.  
  3. {$I SHUNITSW.INC}
  4.  
  5. {$V-}
  6.  
  7. unit TestFin;
  8. {This unit tests the ShFinanc unit over a range of values. Both Ordinary
  9.  Annuities and Annuities Due are tested.}
  10.  
  11. interface
  12.  
  13. uses
  14.   TpCrt,
  15.   TpDos,
  16.   TpString,
  17.   shFinanc,
  18.   shErrMsg;
  19.  
  20. procedure TestFinance;
  21.  
  22. implementation
  23.  
  24. type
  25. {$IFNDEF Gen87}
  26.   extended = real;
  27.   Float           = real;
  28. {$ELSE}
  29.   Float           = extended;
  30. {$ENDIF}
  31.  
  32. const
  33.   TestDesc  : array[1..6] of string[65] =
  34.       ('In the following, for each set of I(nterest rate), N(umber of',
  35.        'payments), and T(ype of annuity, an expected result for the',
  36.        'calculation being performed will be displayed, followed by the',
  37.        'actual result. The expected results are taken from the appro-',
  38.        'priate tables in Smail, L.L., "Mathematics of Finance",',
  39.        'McGraw-Hill, 1953.');
  40.  
  41.   IntTstDsc : array[1..10] of string[65] =
  42.        ('In the following interactive test, you will be asked for three',
  43.         'values; Interest (if percentage suffix with a "%"), Number of Pay-',
  44.         'ment Periods, and Type of the annuity ((O)rdinary (i.e., payments',
  45.         'are made at the END of the conversion period), and (D)ue (the',
  46.         'payments are made at the BEGINNING of the conversion period)).',
  47.         'Following input of the annuity type, calculated results will be',
  48.         'displayed.',
  49.         '',
  50.         'The sequence will be repeated as often as desired. Use an inter-',
  51.         'est rate of 0 to exit the program.');
  52.  
  53.   NumI  = 4;
  54.   NumN  = 4;
  55.   NumT  = 4;
  56.   NumTst= 6;
  57.   TestTtl   : array[1..NumTst] of string[25] =
  58.                ('Compound Amount',
  59.                 'Compound Present Value',
  60.                 'Annuity Amount',
  61.                 'Annuity Present Value',
  62.                 '''N'' from Ann. Pres. Val.',
  63.                 '''I'' from Ann. Pres. Val.');
  64.   TestsI    : array[1..NumI] of extended =
  65.                 (0.005, 0.030, 0.050, 0.080);
  66.   TestsN    : array[1..NumN] of integer   =
  67.                 (  1, 33, 70, 100);
  68.   TestsT    : array[AnnType] of string[18] =
  69.                 ('Ordinary Annuity', 'Annuity Due');
  70.   TestsE    : array[1..NumI, 1..NumN, AnnType, 1..NumT] of Float =
  71.        (
  72.        {I = 0.005}
  73.          (
  74.          {N = 1}
  75.            (
  76.            {T = Ordinary}
  77.              {Comp. Amt}   {Pres. Val}  {Ann.  Amt}  {Ann Pres Val}
  78.              (   1.0050000, 0.9950249,     1.0000000,  0.9950249   ),
  79.            {T = Due}
  80.              {Comp. Amt}   {Pres. Val}  {Ann.  Amt}  {Ann Pres Val}
  81.              (   1.0050000, 0.9950249,     1.0050000,  1.0000000   )
  82.                                                    {End of N =   1}),
  83.  
  84.          {N = 33}
  85.            (
  86.            {T = Ordinary}
  87.              {Comp. Amt}   {Pres. Val}  {Ann.  Amt}  {Ann Pres Val}
  88.              (   1.1789083, 0.8482424,    35.7816669, 30.3515259   ),
  89.            {T = Due}
  90.              {Comp. Amt}   {Pres. Val}  {Ann.  Amt}  {Ann Pres Val}
  91.              (   1.1789083, 0.8482424,    35.9605752, 30.5032835   )
  92.                                                    {End of N =  33}),
  93.  
  94.          {N = 70}
  95.            (
  96.            {T = Ordinary}
  97.              {Comp. Amt}   {Pres. Val}  {Ann.  Amt}  {Ann Pres Val}
  98.              (   1.4178305, 0.7053029,    83.5661055, 58.9394176   ),
  99.            {T = Due}
  100.              {Comp. Amt}   {Pres. Val}  {Ann.  Amt}  {Ann Pres Val}
  101.              (   1.4178305, 0.7053029,    83.9839360, 59.2341147   )
  102.                                                    {End of N =  70}),
  103.  
  104.          {N = 100}
  105.            (
  106.            {T = Ordinary}
  107.              {Comp. Amt}   {Pres. Val}  {Ann.  Amt}  {Ann Pres Val}
  108.              (   1.6466685, 0.6072868,   129.3336984, 78.5426448   ),
  109.            {T = Due}
  110.              {Comp. Amt}   {Pres. Val}  {Ann.  Amt}  {Ann Pres Val}
  111.              (   1.6466685, 0.6072868,   129.9803669, 78.9353580   )
  112.                                                    {End of N = 100})
  113.                                                  {End of I = 0.005}),
  114.  
  115.        {I = 0.030}
  116.          (
  117.          {N = 1}
  118.            (
  119.            {T = Ordinary}
  120.              {Comp. Amt}   {Pres. Val}  {Ann.  Amt}  {Ann Pres Val}
  121.              (   1.0300000, 0.9708738,     1.0000000,  0.9708738   ),
  122.            {T = Due}
  123.              {Comp. Amt}   {Pres. Val}  {Ann.  Amt}  {Ann Pres Val}
  124.              (   1.0300000, 0.9708738,     1.0300000,  1.0000000   )
  125.                                                    {End of N =   1}),
  126.  
  127.          {N = 33}
  128.            (
  129.            {T = Ordinary}
  130.              {Comp. Amt}   {Pres. Val}  {Ann.  Amt}  {Ann Pres Val}
  131.              (   2.6523352, 0.3770262,    55.0778413, 20.7657918   ),
  132.            {T = Due}
  133.              {Comp. Amt}   {Pres. Val}  {Ann.  Amt}  {Ann Pres Val}
  134.              (   2.6523352, 0.3770262,    56.7301765, 21.3887656   )
  135.                                                    {End of N =  33}),
  136.  
  137.          {N = 70}
  138.            (
  139.            {T = Ordinary}
  140.              {Comp. Amt}   {Pres. Val}  {Ann.  Amt}  {Ann Pres Val}
  141.              (   7.9178219, 0.1262974,   230.5940637, 29.1234214   ),
  142.            {T = Due}
  143.              {Comp. Amt}   {Pres. Val}  {Ann.  Amt}  {Ann Pres Val}
  144.              (   7.9178219, 0.1262974,   237.5118856, 29.9971240   )
  145.                                                    {End of N =  70}),
  146.  
  147.          {N = 100}
  148.            (
  149.            {T = Ordinary}
  150.              {Comp. Amt}   {Pres. Val}  {Ann.  Amt}  {Ann Pres Val}
  151.              (  19.2186320, 0.0520328,   607.2877327, 31.5989053   ),
  152.            {T = Due}
  153.              {Comp. Amt}   {Pres. Val}  {Ann.  Amt}  {Ann Pres Val}
  154.              (  19.2186320, 0.0520328,   625.5063647, 32.5468725   )
  155.                                                    {End of N = 100})
  156.                                                  {End of I = 0.030}),
  157.  
  158.        {I = 0.050}
  159.          (
  160.          {N = 1}
  161.            (
  162.            {T = Ordinary}
  163.              {Comp. Amt}   {Pres. Val}  {Ann.  Amt}  {Ann Pres Val}
  164.              (   1.0500000, 0.9523810,     1.0000000,  0.9523810   ),
  165.            {T = Due}
  166.              {Comp. Amt}   {Pres. Val}  {Ann.  Amt}  {Ann Pres Val}
  167.              (   1.0500000, 0.9523810,     1.0500000,  1.0000000   )
  168.                                                    {End of N =   1}),
  169.  
  170.          {N = 33}
  171.            (
  172.            {T = Ordinary}
  173.              {Comp. Amt}   {Pres. Val}  {Ann.  Amt}  {Ann Pres Val}
  174.              (   5.0031885, 0.1998725,    80.0637708, 16.0025492   ),
  175.            {T = Due}
  176.              {Comp. Amt}   {Pres. Val}  {Ann.  Amt}  {Ann Pres Val}
  177.              (   5.0031885, 0.1998725,    84.0669593, 16.8026767   )
  178.                                                    {End of N =  33}),
  179.  
  180.          {N = 70}
  181.            (
  182.            {T = Ordinary}
  183.              {Comp. Amt}   {Pres. Val}  {Ann.  Amt}  {Ann Pres Val}
  184.              (  30.4264255, 0.0328662,   588.5285107, 19.3426766   ),
  185.            {T = Due}
  186.              {Comp. Amt}   {Pres. Val}  {Ann.  Amt}  {Ann Pres Val}
  187.              (  30.4264255, 0.0328662,   617.9549362, 20.3098104   )
  188.                                                    {End of N =  70}),
  189.  
  190.          {N = 100}
  191.            (
  192.            {T = Ordinary}
  193.              {Comp. Amt}   {Pres. Val}  {Ann.  Amt}  {Ann Pres Val}
  194.              ( 131.5012578, 0.0076045,  2610.0251569, 19.8479102   ),
  195.            {T = Due}
  196.              {Comp. Amt}   {Pres. Val}  {Ann.  Amt}  {Ann Pres Val}
  197.              ( 131.5012578, 0.0076045,  2740.5264147, 20.8403057   )
  198.                                                    {End of N = 100})
  199.                                                  {End of I = 0.050}                  ),
  200.  
  201.        {I = 0.080}
  202.          (
  203.          {N = 1}
  204.            (
  205.            {T = Ordinary}
  206.              {Comp. Amt}   {Pres. Val}  {Ann.  Amt}  {Ann Pres Val}
  207.              (   1.0800000, 0.9259259,   1.0000000,    0.9259259   ),
  208.            {T = Due}
  209.              {Comp. Amt}   {Pres. Val}  {Ann.  Amt}  {Ann Pres Val}
  210.              (   1.0800000, 0.9259259,   1.0800000,    1.0000000  )
  211.                                                   {End of N =   1}),
  212.  
  213.          {N = 33}
  214.            (
  215.            {T = Ordinary}
  216.              {Comp. Amt}   {Pres. Val}  {Ann.  Amt}  {Ann Pres Val}
  217.              (  12.6760496, 0.0788889,   145.9506204, 11.5138884   ),
  218.            {T = Due}
  219.              {Comp. Amt}   {Pres. Val}  {Ann.  Amt}  {Ann Pres Val}
  220.              (  12.6760496, 0.0788889,   157.6266700, 12.4349995   )
  221.                                                    {End of N =  33}),
  222.  
  223.          {N = 70}
  224.            (
  225.            {T = Ordinary}
  226.              {Comp. Amt}   {Pres. Val}  {Ann.  Amt}  {Ann Pres Val}
  227.              ( 218.6064059, 0.0045744,  2720.0800738, 12.4428196   ),
  228.            {T = Due}
  229.              {Comp. Amt}   {Pres. Val}  {Ann.  Amt}  {Ann Pres Val}
  230.              ( 218.6064059, 0.0045744,  2937.6864797, 13.4382452   )
  231.                                                    {End of N =  70}),
  232.  
  233.          {N = 100}
  234.            (
  235.            {T = Ordinary}
  236.              {Comp. Amt}   {Pres. Val}  {Ann.  Amt}  {Ann Pres Val}
  237.              (2199.7612563, 0.0004546, 27484.5157043, 12.4943176   ),
  238.            {T = Due}
  239.              {Comp. Amt}   {Pres. Val}  {Ann.  Amt}  {Ann Pres Val}
  240.              (2199.7612563, 0.0004546, 29683.2769606, 13.4938630   )
  241.                                                    {End of N = 100})
  242.                                                  {End of I = 0.080})
  243.                                          {End of TestsE Definition});
  244.  
  245.   RW  : byte = 14;    {Field width for real-type reference values}
  246.   RP  : byte =  7;    {Decimal places for real-type reference values}
  247.   ISp =  5;           {Interest lead-in spacing}
  248.   NSp =  7;           {Num Pay  lead-in spacing}
  249.   TSp =  9;           {Type     lead-in spacing}
  250.   FSp = 11;           {Function lead-in spacing}
  251.   VSp = 13;           {Value    lead-in spacing}
  252.  
  253. procedure TestFinance;
  254.   var
  255.     ISt : string;
  256.     EC  : integer;
  257.     E1,
  258.     I,
  259.     APV,
  260.     IPV : Float;
  261.     N   : integer;
  262.     T   : AnnType;
  263.     TT  : string;
  264.     IxI,                            {Interest index}
  265.     IxN,                            {Payment periods index}
  266.     IxTT: ShortInt;                 {Tests index}
  267.     IxT : AnnType;                  {Annuity type index}
  268.     S1  : string;
  269.     O   : text;
  270.  
  271.   procedure AnyKey;
  272.     begin
  273.       if HandleIsConsole(1) then begin
  274.         Write('Any key to continue... ');
  275.         if ReadKey = #0 then ;
  276.         GoToXY(1, WhereY);
  277.         DelLine;
  278.         end;
  279.       end;
  280.  
  281.   procedure WriteValue(E : Float);
  282.     begin
  283.       S1 := finErrMsg(finErrCode);
  284.       if S1 = '' then
  285.         WriteLn(O, E:FW:DP)
  286.       else
  287.         WriteLn(O, S1);
  288.       end;
  289.  
  290.   procedure WriteIvalue(I : integer);
  291.     begin {WriteIvalue}
  292.       S1 := finErrMsg(finErrCode);
  293.       if S1 = '' then
  294.         WriteLn(O, I:IW)
  295.       else
  296.         WriteLn(O, S1);
  297.       end; {WriteIvalue}
  298.  
  299.   begin {TestFinance}
  300.     if OpenStdDev(O, 1) then ;
  301.     CheckOn;
  302.     finErrCheckOff;
  303.  
  304.     WriteLn(O);
  305.     for N := 1 to 6 do
  306.       WriteLn(O, '':5,TestDesc[N]);
  307.  
  308.     for IxI := 1 to NumI do begin
  309.       I := TestsI[IxI];
  310.       for IxN := 1 to NumN do begin
  311.         N := TestsN[IxN];
  312.         for IxT := Ordinary to Due do begin
  313.           for IxTT := 1 to NumTst do begin
  314.             case IxTT of
  315.               1 : begin
  316.                     WriteLn(O);
  317.                     AnyKey;
  318.                     WriteLn(O, '':ISp,'For I = ',(I*100.0):3:1,'%');
  319.                     WriteLn(O, '':NSp,'For N = ', N:3);
  320.                     WriteLn(O, '':TSp,'For Type = ',TestsT[IxT]);
  321.  
  322.                     WriteLn(O, '':FSp,'For Function = ',TestTtl[IxTT]);
  323.                     Write  (O, '':VSp,'Calculated = ');
  324.                     WriteValue(CompAmount(N, I));
  325.                     WriteLn(O, '':VSp,'Reference  = ',
  326.                                   TestsE[IxI, IxN, IxT, IxTT]:RW:RP);
  327.                     end;
  328.               2 : begin
  329.                     WriteLn(O, '':FSp,'For Function = ',TestTtl[IxTT]);
  330.                     Write  (O, '':VSp,'Calculated = ');
  331.                     WriteValue(CompPresVal(N, I));
  332.                     WriteLn(O, '':VSp,'Reference  = ',
  333.                                   TestsE[IxI, IxN, IxT, IxTT]:RW:RP);
  334.                     end;
  335.               3 : begin
  336.                     WriteLn(O, '':FSp,'For Function = ',TestTtl[IxTT]);
  337.                     Write  (O, '':VSp,'Calculated = ');
  338.                     WriteValue(AnnuityAmount(N, I, IxT));
  339.                     WriteLn(O, '':VSp,'Reference  = ',
  340.                                   TestsE[IxI, IxN, IxT, IxTT]:RW:RP);
  341.                     end;
  342.               4 : begin
  343.                     WriteLn(O, '':FSp,'For Function = ',TestTtl[IxTT]);
  344.                     Write  (O, '':VSp,'Calculated = ');
  345.                     APV := AnnuityPresVal(N, I, IxT);
  346.                     WriteValue(APV);
  347.                     WriteLn(O, '':VSp,'Reference  = ',
  348.                                   TestsE[IxI, IxN, IxT, IxTT]:RW:RP);
  349.                     end;
  350.               5 : begin
  351.                     WriteLn(O, '':FSp,'For Function = ',TestTtl[IxTT]);
  352.                     Write  (O, '':VSp,'Calculated = ');
  353.                     WriteIvalue(NumPay(APV, I, IxT));
  354.                     WriteLn(O, '':VSp,'Reference  = ',
  355.                                   N:IW);
  356.                     end;
  357.               6 : begin
  358.                     WriteLn(O, '':FSp,'For Function = ',TestTtl[IxTT]);
  359.                     Write  (O, '':VSp,'Calculated = ');
  360.                     WriteValue(IfromPresVal(APV, N, IxT, 1.0E-9));
  361.                     WriteLn(O, '':VSp,'Reference  = ',
  362.                                   I:RW:RP);
  363.                     end;
  364.               end; {case}
  365.             end; {for IxTT}
  366.  
  367.             if (IxT = Due)                  and
  368.               ((IxN < NumN)       or
  369.                (IxI < NumI))                and
  370.                (not (HandleIsConsole(1)))   then begin
  371.               Write(O, ^L);
  372.               end;
  373.  
  374.           end; {for IxT}
  375.         end; {for IxN}
  376.       end; {for IxI}
  377.  
  378.     WriteLn(O);
  379.     AnyKey;
  380.  
  381.     if not HandleIsConsole(1) then begin
  382.       WriteLn(O, '':TSp,
  383.               'Interactive mode testing not available under redirection.');
  384.       Close(O);
  385.       exit;
  386.       end;
  387.  
  388.     WriteLn;
  389.     for N := 1 to 10 do
  390.       WriteLn('':5,IntTstDsc[N]);
  391.     WriteLn;
  392.  
  393.     repeat
  394.       write('     ..Interest rate » '); readln(ISt);
  395.       Val(ISt, I, EC);
  396.       if (EC <> 0) and (ISt[EC] = '%') then begin
  397.         ISt[0] := char(pred(EC));
  398.         Val(ISt, I, EC);
  399.         if EC = 0 then begin
  400.           I := I / 100.0;
  401.           end
  402.         else begin
  403.           I := 0.0;
  404.           end;
  405.         end;
  406.       if I <= 0.0 then
  407.         exit;
  408.       write('Number of payments » '); readln(N);
  409.       write('   Type of annuity » '); readln(TT);
  410.       finErrCheckOff;
  411.       case Upcase(TT[1]) of
  412.         'O' : T := Ordinary;
  413.         'D' : T := Due;
  414.         end; {case}
  415.       APV := AnnuityPresVal(N, I, T);
  416.       writeln;
  417.       writeln('Annuity present value = ',APV:FW:DP);
  418.       write(finErrMsg(finErrCode)); if WhereX <> 1 then WriteLn;
  419.       writeln('Number of payments = ',NumPay(APV, I, T):IW);
  420.       write(finErrMsg(finErrCode)); if WhereX <> 1 then WriteLn;
  421.       writeln;
  422.       writeln('Ann. pres. val. as discounted ann. amt. = ',
  423.                (CompPresVal(N, I) * AnnuityAmount(N, I, T)):FW:DP);
  424.       write(finErrMsg(finErrCode)); if WhereX <> 1 then WriteLn;
  425.       writeln;
  426. {$IFDEF Gen87}
  427.       IPV := IfromPresVal(APV, N, T, 1.0E-15);
  428. {$ELSE}
  429.       IPV := IfromPresVal(APV, N, T, 1.0E-09);
  430. {$ENDIF}
  431.       write(finErrMsg(finErrCode)); if WhereX <> 1 then WriteLn;
  432.       writeln('Interest rate = ',IPV:FW:DP);
  433.       writeln;
  434.       writeln(Center('* * * * * * * * * * * * * * * * *', 72));
  435.       writeln;
  436.       until false;
  437.     end; {TestFinance}
  438.   end.
  439.